import json

from chatterbot.ext.django_chatterbot import settings
from ckeditor_uploader import utils
from ckeditor_uploader.backends import registry
from ckeditor_uploader.utils import get_storage_class
from ckeditor_uploader.views import get_upload_filename
from django.http import JsonResponse, HttpRequest, HttpResponse, Http404
from django.views.generic import View
from django.views.generic.base import TemplateView

from chatbot.bot.domain.question import Question
from chatbot.service.init.chat_box_initialize import get_chat_box_initialization


class WebChatBox(TemplateView):
    template_name = 'chatbot/chatbox.html'


class ChatBotApi(View):
    """
    Provide an API endpoint to interact with ChatBot.
    """

    def post(self, request, *args, **kwargs):
        """
        Return a response to the statement in the posted data.

        * The JSON data should contain a 'text' attribute.
        """
        input_data = json.loads(request.body.decode('utf-8'))

        if 'text' not in input_data:
            return JsonResponse({
                'text': [
                    'The attribute "text" is required.'
                ]
            }, status=400)
        bot = self._get_session(request).bot
        question = Question(text=input_data.get('text', ''))
        response = bot.get_response(question)

        response_data = response.serialize()

        return JsonResponse(response_data, status=200)

    def get(self, request: HttpRequest, channel_id, *args, **kwargs):
        """
        Return chat box initialization data to the current conversation.
        """
        if not channel_id:
            return Http404
        session = self._get_session(request, channel_id)
        context = get_chat_box_initialization(session).serialize()
        response = JsonResponse(context)
        session.set_cookie(request, response)
        return response

    @staticmethod
    def _get_session(request, channel_id=None):
        from chatbot.service.session.session_manager import SessionManager
        session_manager = SessionManager(request, channel_id)
        session = session_manager.get_session(request, channel_id)
        return session


class ChatBotUpload(View):
    storage = get_storage_class()

    def post(self, request: HttpRequest, *args, **kwargs):
        response = None
        if request.method == 'POST' and request.FILES:

            uploaded_file = request.FILES['file']

            backend = registry.get_backend()

            file_wrapper = backend(self.storage, uploaded_file)
            allow_non_images = getattr(settings, 'CKEDITOR_ALLOW_NONIMAGE_FILES', True)
            # Throws an error when an non-image file are uploaded.
            if not file_wrapper.is_image and not allow_non_images:
                response = {
                    "code": 1,
                    "msg": "我看不懂图片的意思哦，能否用语言再描述一下啊",
                    "data": {"src": ""}
                }
                return HttpResponse(json.dumps(response), content_type="application/json")

            filepath = get_upload_filename(uploaded_file.name, request)

            saved_path = file_wrapper.save_as(filepath)
            url = utils.get_media_url(saved_path)

            response = {
                "code": 0,
                "msg": url,
                "data": {"src": url}
            }

        return HttpResponse(json.dumps(response), content_type="application/json")
